home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / src.arc / TCPCMD.C < prev    next >
C/C++ Source or Header  |  1989-08-19  |  7KB  |  290 lines

  1. #include <stdio.h>
  2. #include "global.h"
  3. #include "timer.h"
  4. #include "mbuf.h"
  5. #include "netuser.h"
  6. #include "internet.h"
  7. #include "tcp.h"
  8. #include "cmdparse.h"
  9. #include "commands.h"
  10.  
  11. extern char Notval[];
  12.  
  13. static int doirtt __ARGS((int argc,char *argv[],void *p));
  14. static int domss __ARGS((int argc,char *argv[],void *p));
  15. static int dortt __ARGS((int argc,char *argv[],void *p));
  16. static int dotcpkick __ARGS((int argc,char *argv[],void *p));
  17. static int dotcpreset __ARGS((int argc,char *argv[],void *p));
  18. static int dotcpstat __ARGS((int argc,char *argv[],void *p));
  19. static int dotcptr __ARGS((int argc,char *argv[],void *p));
  20. static int dowindow __ARGS((int argc,char *argv[],void *p));
  21. static int tstat __ARGS((void));
  22.  
  23. /* TCP subcommand table */
  24. static struct cmds Tcpcmds[] = {
  25.     "irtt",        doirtt,        0, 0,    NULLCHAR,
  26.     "kick",        dotcpkick,    0, 2,    "tcp kick <tcb>",
  27.     "mss",        domss,        0, 0,    NULLCHAR,
  28.     "reset",    dotcpreset,    0, 2,    "tcp reset <tcb>",
  29.     "rtt",        dortt,        0, 3,    "tcp rtt <tcb> <val>",
  30.     "status",    dotcpstat,    0, 0,    NULLCHAR,
  31.     "trace",    dotcptr,    0, 0,    NULLCHAR,
  32.     "window",    dowindow,    0, 0,    NULLCHAR,
  33.     NULLCHAR,
  34. };
  35. int
  36. dotcp(argc,argv,p)
  37. int argc;
  38. char *argv[];
  39. void *p;
  40. {
  41.     return subcmd(Tcpcmds,argc,argv,p);
  42. }
  43. static int
  44. dotcptr(argc,argv,p)
  45. int argc;
  46. char *argv[];
  47. void *p;
  48. {
  49.     return setbool(&Tcp_trace,"TCP state tracing",argc,argv);
  50. }
  51.  
  52. /* Eliminate a TCP connection */
  53. static int
  54. dotcpreset(argc,argv,p)
  55. int argc;
  56. char *argv[];
  57. void *p;
  58. {
  59.     register struct tcb *tcb;
  60.  
  61.     tcb = (struct tcb *)ltop(htol(argv[1]));
  62.     if(!tcpval(tcb)){
  63.         printf(Notval);
  64.         return 1;
  65.     }
  66.     close_self(tcb,RESET);
  67.     return 0;
  68. }
  69.  
  70. /* Set initial round trip time for new connections */
  71. static int
  72. doirtt(argc,argv,p)
  73. int argc;
  74. char *argv[];
  75. void *p;
  76. {
  77.     struct tcp_rtt *tp;
  78.  
  79.     setlong(&Tcp_irtt,"TCP default irtt",argc,argv);
  80.     if(argc < 2){
  81.         for(tp = &Tcp_rtt[0];tp < &Tcp_rtt[RTTCACHE];tp++){
  82.             if(tp->addr != 0){
  83.                 printf("%s: srtt %lu mdev %lu\n",
  84.                     inet_ntoa(tp->addr),
  85.                     tp->srtt,tp->mdev);
  86.             }
  87.         }
  88.     }
  89.     return 0;
  90. }
  91.  
  92. /* Set smoothed round trip time for specified TCB */
  93. static int
  94. dortt(argc,argv,p)
  95. int argc;
  96. char *argv[];
  97. void *p;
  98. {
  99.     register struct tcb *tcb;
  100.  
  101.     tcb = (struct tcb *)ltop(htol(argv[1]));
  102.     if(!tcpval(tcb)){
  103.         printf(Notval);
  104.         return 1;
  105.     }
  106.     tcb->srtt = atol(argv[2]);
  107.     return 0;
  108. }
  109.  
  110. /* Force a retransmission */
  111. static int
  112. dotcpkick(argc,argv,p)
  113. int argc;
  114. char *argv[];
  115. void *p;
  116. {
  117.     register struct tcb *tcb;
  118.  
  119.     tcb = (struct tcb *)ltop(htol(argv[1]));
  120.     if(kick_tcp(tcb) == -1){
  121.         printf(Notval);
  122.         return 1;
  123.     }
  124.     return 0;
  125. }
  126.  
  127. /* Set default maximum segment size */
  128. static int
  129. domss(argc,argv,p)
  130. int argc;
  131. char *argv[];
  132. void *p;
  133. {
  134.     return setshort(&Tcp_mss,"TCP MSS",argc,argv);
  135. }
  136.  
  137. /* Set default window size */
  138. static int
  139. dowindow(argc,argv,p)
  140. int argc;
  141. char *argv[];
  142. void *p;
  143. {
  144.     return setshort(&Tcp_window,"TCP window",argc,argv);    
  145. }
  146.  
  147. /* Display status of TCBs */
  148. static int
  149. dotcpstat(argc,argv,p)
  150. int argc;
  151. char *argv[];
  152. void *p;
  153. {
  154.     register struct tcb *tcb;
  155.  
  156.     if(argc < 2){
  157.         tstat();
  158.     } else {
  159.         tcb = (struct tcb *)ltop(htol(argv[1]));
  160.         if(tcpval(tcb))
  161.             st_tcp(tcb);
  162.         else
  163.             printf(Notval);
  164.     }
  165.     return 0;
  166. }
  167.  
  168. /* Dump TCP stats and summary of all TCBs
  169. /*     &TCB Rcv-Q Snd-Q  Local socket           Remote socket          State
  170.  *     1234     0     0  xxx.xxx.xxx.xxx:xxxxx  xxx.xxx.xxx.xxx:xxxxx  Established
  171.  */
  172. static int
  173. tstat()
  174. {
  175.     register int i;
  176.     register struct tcb *tcb;
  177.  
  178.     printf("conout %u conin %u reset out %u runt %u chksum err %u bdcsts %u\n",
  179.         Tcp_stat.conout,Tcp_stat.conin,Tcp_stat.resets,Tcp_stat.runt,
  180.         Tcp_stat.checksum,Tcp_stat.bdcsts);
  181.     printf("    &TCB Rcv-Q Snd-Q  Local socket           Remote socket          State\n");
  182.     for(i=0;i<NTCB;i++){
  183.         for(tcb=Tcbs[i];tcb != NULLTCB;tcb = tcb->next){
  184.             printf("%8lx%6u%6u  ",ptol(tcb),tcb->rcvcnt,tcb->sndcnt);
  185.             printf("%-23s",pinet(&tcb->conn.local));
  186.             printf("%-23s",pinet(&tcb->conn.remote));
  187.             printf("%-s",Tcpstates[tcb->state]);
  188.             if(tcb->state == LISTEN && tcb->flags.clone)
  189.                 printf(" (S)");
  190.             printf("\n");
  191.         }
  192.     }
  193.     return 0;
  194. }
  195. /* Dump a TCP control block in detail */
  196. void
  197. st_tcp(tcb)
  198. struct tcb *tcb;
  199. {
  200.     int32 sent,recvd;
  201.  
  202.     if(tcb == NULLTCB)
  203.         return;
  204.     /* Compute total data sent and received; take out SYN and FIN */
  205.     sent = tcb->snd.una - tcb->iss;    /* Acknowledged data only */
  206.     recvd = tcb->rcv.nxt - tcb->irs;
  207.     switch(tcb->state){
  208.     case LISTEN:
  209.     case SYN_SENT:        /* Nothing received or acked yet */
  210.         sent = recvd = 0;    
  211.         break;
  212.     case SYN_RECEIVED:
  213.         recvd--;    /* Got SYN, no data acked yet */
  214.         sent = 0;
  215.         break;
  216.     case ESTABLISHED:    /* Got and sent SYN */
  217.     case FINWAIT1:        /* FIN not acked yet */
  218.         sent--;
  219.         recvd--;
  220.         break;
  221.     case FINWAIT2:        /* Our SYN and FIN both acked */
  222.         sent -= 2;
  223.         recvd--;
  224.         break;
  225.     case CLOSE_WAIT:    /* Got SYN and FIN, our FIN not yet acked */
  226.     case CLOSING:
  227.     case LAST_ACK:
  228.         sent--;
  229.         recvd -= 2;
  230.         break;
  231.     case TIME_WAIT:        /* Sent and received SYN/FIN, all acked */
  232.         sent -= 2;
  233.         recvd -= 2;
  234.         break;
  235.     }
  236.     printf("Local: %s",pinet(&tcb->conn.local));
  237.     printf(" Remote: %s",pinet(&tcb->conn.remote));
  238.     printf(" State: %s\n",Tcpstates[tcb->state]);
  239.     printf("      Init seq    Unack     Next Resent CWind Thrsh  Wind  MSS Queue      Total\n");
  240.     printf("Send:");
  241.     printf("%9lx",tcb->iss);
  242.     printf("%9lx",tcb->snd.una);
  243.     printf("%9lx",tcb->snd.nxt);
  244.     printf("%7lu",tcb->resent);
  245.     printf("%6u",tcb->cwind);
  246.     printf("%6u",tcb->ssthresh);
  247.     printf("%6u",tcb->snd.wnd);
  248.     printf("%5u",tcb->mss);
  249.     printf("%6u",tcb->sndcnt);
  250.     printf("%11lu\n",sent);
  251.  
  252.     printf("Recv:");
  253.     printf("%9lx",tcb->irs);
  254.     printf("         ");
  255.     printf("%9lx",tcb->rcv.nxt);
  256.     printf("%7lu",tcb->rerecv);
  257.     printf("      ");
  258.     printf("      ");
  259.     printf("%6u",tcb->rcv.wnd);
  260.     printf("     ");
  261.     printf("%6u",tcb->rcvcnt);
  262.     printf("%11lu\n",recvd);
  263.  
  264.     if(tcb->reseq != (struct reseq *)NULL){
  265.         register struct reseq *rp;
  266.  
  267.         printf("Reassembly queue:\n");
  268.         for(rp = tcb->reseq;rp != (struct reseq *)NULL; rp = rp->next){
  269.             printf("  seq x%lx %u bytes\n",rp->seg.seq,rp->length);
  270.         }
  271.     }
  272.     if(tcb->backoff > 0)
  273.         printf("Backoff %u ",tcb->backoff);
  274.     if(tcb->flags.retran)
  275.         printf("Retrying ");
  276.     switch(tcb->timer.state){
  277.     case TIMER_STOP:
  278.         printf("Timer stopped ");
  279.         break;
  280.     case TIMER_RUN:
  281.         printf("Timer running (%ld/%ld ms) ",
  282.          (long)MSPTICK * read_timer(&tcb->timer),
  283.          (long)MSPTICK * dur_timer(&tcb->timer));
  284.         break;
  285.     case TIMER_EXPIRE:
  286.         printf("Timer expired ");
  287.     }
  288.     printf("SRTT %ld ms Mean dev %ld ms\n",tcb->srtt,tcb->mdev);
  289. }
  290.